// CNumEdit.cpp : Implementierungsdatei
//

#include "stdafx.h"
#include "CNumEdit.h"
#include ".\cnumedit.h"


// CNumEdit

IMPLEMENT_DYNAMIC(CNumEdit, CWnd)
CNumEdit::CNumEdit()
{
    mb_show_range = false;
	mb_only_num = TRUE;
	SetColorsDefault();
}

CNumEdit::~CNumEdit()
{
}


void	CNumEdit::SetTextColor(COLORREF col)
{
	m_clrText = col;
}

void	CNumEdit::SetBackground(COLORREF col)
{
	m_clrBkgnd = col;
	m_brBkgnd.DeleteObject();
	m_brBkgnd.CreateSolidBrush( m_clrBkgnd );
    if (IsWindow(m_hWnd))
        Invalidate(false);
}


void	CNumEdit::SetColorsDefault()
{
	SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
	SetBackground(GetSysColor(COLOR_WINDOW));
    if (IsWindow(m_hWnd))
        Invalidate(false);
}


HBRUSH CNumEdit::OnCtlColor(CDC* pDC, CWnd* , UINT )
{
	pDC->SetTextColor( m_clrText );   // text
	pDC->SetBkColor( m_clrBkgnd );   // text bkgnd
	return m_brBkgnd;            // ctl bkgnd
}


// ===========================
//  Create
//    Creates the Child controls
// ===========================
BOOL CNumEdit::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
	CWnd::Create(NULL,_T("CNumEdit"),dwStyle, rect, pParentWnd, nID,NULL);

	// calc size
	int h = rect.bottom - rect.top;
	int w = rect.right - rect.left;
	int bw = h;

	// Create childs
	button1.Create(_T("<"),WS_CHILD|WS_VISIBLE|  BS_DEFPUSHBUTTON | BS_OWNERDRAW | WS_GROUP,
				   CRect(0,0,bw,h), this, 1);
	button2.Create(_T(">"),WS_CHILD|WS_VISIBLE|  BS_DEFPUSHBUTTON | BS_OWNERDRAW ,
				   CRect(w-bw,0,w,h), this, 2);

	edit.Create(ES_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP | (mb_only_num?ES_NUMBER:0),
					CRect(bw,0,w-bw,h),this,3);

	// make sure we take the same font as the parent
	edit.SetFont(pParentWnd->GetFont());

	number = 0;
	n_min = 0;
	n_max = 50;

	// show default value
	ShowNumber();

	return TRUE;
}


void	CNumEdit::ShowNumber()
{
	CString temp;
	temp.Format(_T("%i"),number);
	edit.SetWindowText(temp);

    button1.EnableWindow(number > n_min);
    button2.EnableWindow(number < n_max);
}


// ===========================
//  OnSite
//    Resize the Child windows
// ===========================
void CNumEdit::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	if (!IsWindow(button1.GetSafeHwnd())) return;

	int h = cy;
	int w = cx;
	int bw = h;

	button1.MoveWindow(0,0,bw,h);
	button2.MoveWindow(w-bw,0,bw,h);
	edit.MoveWindow(bw,0,w-2*bw,h);
}



BEGIN_MESSAGE_MAP(CNumEdit, CWnd)
ON_WM_SETFOCUS()
ON_WM_SIZE()
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()



// CNumEdit-Meldungshandler

// ===========================
//  SetRange
//    Set min/max and check the value (this doesn't use SetValue, 'cause I don't want the message to be send)
// ===========================
void	CNumEdit::SetRange(int min, int max)
{
	n_min = min;
	n_max = max;

    if (mb_show_range)
    {
        if (n_min>1)    button1.SetBackground(RGB(192,255,192));
        else            button1.SetDefaultBackground();
        if (n_max<50)   button2.SetBackground(RGB(192,255,192));
        else            button2.SetDefaultBackground();
    }

    button1.EnableWindow(number > n_min);
    button2.EnableWindow(number < n_max);

	int val;
	val = max(n_min,number);
	val = min(n_max,number);
	if (number == val) return;
	number = val;

	ShowNumber();
}

//////////////////////////////////////////////////////////////////////////
void    CNumEdit::ShowRangeColors(bool b_show /*=true*/)
{
    if (mb_show_range==b_show)  return;

    mb_show_range=b_show;

    if (mb_show_range)
        SetRange(n_min, n_max);
    else
    {
        button1.SetDefaultBackground();
        button2.SetDefaultBackground();
    }
}




// ===========================
//  SetValue
//    Set the number, checks min/max and if somthing changed
//    If something is change EN_CHANGE will be send to the parents parent
// ===========================
void	CNumEdit::SetValue(int val)
{
	if (!SetValueSilent(val)) return;

	// Send message
	// !! HACK !! -> 'cause this control is only used in CListCtrl
	CWnd* parent = GetParent();
	if (parent)
	{
		parent = parent->GetParent();
		if (parent)
		parent->SendMessage(WM_COMMAND, 
                            MAKELONG(GetDlgCtrlID(), EN_CHANGE), 
                            (LPARAM)m_hWnd);
	}
}


bool	CNumEdit::SetValueSilent(int val)
{
	if (number == val) return false;
	val = max(n_min,val);
	val = min(n_max,val);   
	number = val;

	ShowNumber();
	return true;
}

void	CNumEdit::OnChangeValue(int delta)
{
	if (edit.GetModify())	OnEditLostFocus();

	SetValue(number+delta); 
}

void	CNumEdit::OnEditLostFocus()
{
	CString temp;
	edit.GetWindowText(temp);
	SetValue(_tstoi(temp)); 
}



// ===========================
//  OnCommand
//    Handle child messages
// ===========================
BOOL CNumEdit::OnCommand(WPARAM wParam, LPARAM lParam)
{
	// +/- Buttons
	if (HIWORD(wParam) == BN_CLICKED)
	{
		if (LOWORD(wParam) == 2)
		{
			if (GetAsyncKeyState(VK_SHIFT))
				OnChangeValue(10); 
			else
				OnChangeValue(1); 
			return TRUE;
		}
			
		if (LOWORD(wParam) == 1)
		{
			if (GetAsyncKeyState(VK_SHIFT))
				OnChangeValue(-10); 
			else
				OnChangeValue(-1); 

			return TRUE;
		}
	}


	// EditControl
	if ( LOWORD(wParam) == 3)
	{
		switch (HIWORD(wParam))
		{
			case EN_KILLFOCUS:
				OnEditLostFocus();
				break;

			case EN_KEY_PLUS:
				OnChangeValue(1); 
                RedrawWindow();
				break;

			case EN_KEY_MINUS:
				OnChangeValue(-1); 
                RedrawWindow();
				break;

			// On Cursor UP/DOWN simulate TAB / SHIFT+TAB
			case EN_KEY_UP:
				{
					CWnd*parent = GetParent();
					if (parent)
					{
						CWnd*next = parent->GetNextDlgTabItem(this,true);
						if (next)
							next->SetFocus();
					}
				}
				break;

            case EN_KEY_ENTER:
			case EN_KEY_DOWN:
				{
					CWnd*parent = GetParent();
					if (parent)
					{
						CWnd*next = parent->GetNextDlgTabItem(this,false);
						if (next)
							next->SetFocus();
					}
				}
				break;

		}
	}

	
	   

	

	return CWnd::OnCommand(wParam, lParam);
}


// ===========================
//  OnSetFocus
//    Set focus to the Edit Control
// ===========================
void CNumEdit::OnSetFocus(CWnd* pOldWnd)
{
	CWnd::OnSetFocus(pOldWnd);
	edit.SetFocus();
	edit.SetSel(0,-1);
}

